package com.wan37.logic.tradingshop.handler;

import com.wan37.logic.component.LogicWorkerHandlerCenter;
import com.wan37.logic.component.Worker;
import com.wan37.logic.db.AsynDBManager;
import com.wan37.logic.domain.Result;
import com.wan37.logic.domain.entity.UserDO;
import com.wan37.logic.email.EmailManager;
import com.wan37.logic.global.reference.SpringContextHolder;
import com.wan37.logic.handler.WorkerHandler;
import com.wan37.logic.service.UserService;
import com.wan37.logic.service.cache.UserServiceCache;
import com.wan37.logic.tradingshop.TradingShopManager;
import com.wan37.logic.tradingshop.cache.TradingShopCache;
import com.wan37.logic.tradingshop.domain.vo.TradingShopRecordVO;
import com.wan37.logic.tradingshop.domain.vo.TradingShopVO;
import com.wan37.logic.tradingshop.service.TradingShopRecordService;
import com.wan37.logic.tradingshop.service.TradingShopService;
import com.wan37.logic.tradingshop.util.TradingShopRouteUtil;
import com.wan37.protobuf.constant.CommonTradingShop;

import java.util.List;

/**
 * @author : luoyong
 * @date : 2020-08-06 22:04
 **/
public class AuctionUserBuyHandler implements WorkerHandler {
    private String userId;
    private TradingShopRecordVO tradingShopRecordVO;
    private TradingShopCache tradingShopCache;
    private EmailManager emailManager;
    private TradingShopManager tradingShopManager;
    private AsynDBManager asynDBManager;
    private TradingShopService tradingShopService;
    private TradingShopRecordService tradingShopRecordService;
    private TradingShopRouteUtil tradingShopRouteUtil;
    private UserService userService;
    private UserServiceCache userServiceCache;
    private LogicWorkerHandlerCenter logicWorkerHandlerCenter;
    public AuctionUserBuyHandler(TradingShopRecordVO tradingShopRecordVO, String userId){
        this.tradingShopRecordVO = tradingShopRecordVO;
        this.userId = userId;
        this.tradingShopService = SpringContextHolder.getBean("tradingShopService");
        this.tradingShopRecordService = SpringContextHolder.getBean("tradingShopRecordService");
        this.tradingShopCache = SpringContextHolder.getBean("tradingShopCache");
        this.asynDBManager = SpringContextHolder.getBean("asynDBManager");
        this.emailManager = SpringContextHolder.getBean("emailManager");
        this.tradingShopManager = SpringContextHolder.getBean("tradingShopManager");
        this.tradingShopRouteUtil = SpringContextHolder.getBean("tradingShopRouteUtil");
        this.userService = SpringContextHolder.getBean("userService");
        this.userServiceCache = SpringContextHolder.getBean("userServiceCache");
        this.logicWorkerHandlerCenter = SpringContextHolder.getBean("logicWorkerHandlerCenter");
    }
    @Override
    public void execute(Worker worker) throws Exception {
        if (!tradingShopCache.getTradingShopInMap().containsKey(tradingShopRecordVO.getTradingShopId())){
            tradingShopRouteUtil.sendTradingShopResponse(CommonTradingShop.ERROR, "手慢了，拍卖已经结束了！", userId);
            return;
        }
        TradingShopVO tradingShopVO = tradingShopCache.getTradingShopInMap()
                .get(tradingShopRecordVO.getTradingShopId()).getTradingShopVO();
        UserServiceCache.User user = userServiceCache.getUserServiceMap().get(userId);
        //获取该拍品拍卖纪录，判断之前是否有竞拍记录，进行对应差值扣除金币
        List<TradingShopRecordVO> tradingShopRecordVOList = tradingShopCache.getTradingShopInMap()
                .get(tradingShopVO.getTradingShopId()).getTradingShopRecordVOList();
        if (tradingShopRecordVOList.size() == 0){
            if (tradingShopVO.getIngot() > tradingShopRecordVO.getIngot()){
                tradingShopRouteUtil.sendTradingShopResponse(CommonTradingShop.ERROR, "出价低于用户拍卖的最低价格！", userId);
                return;
            }
            addAuctionTradingShopRecord(user, tradingShopVO, tradingShopRecordVO, tradingShopRecordVO.getIngot());
            return;
        }
        TradingShopRecordVO tradingShopRecordVO1 = null;
        for (TradingShopRecordVO tradingShopRecordVO2 : tradingShopRecordVOList){
            if (tradingShopRecordVO2.getBuyId().equals(userId)){
                tradingShopRecordVO1 = tradingShopRecordVO2;
                break;
            }
        }
        //为空则说明之前没有出价，则直接根据当前出价金额进行扣钱！
        if (tradingShopRecordVO1 == null){
            tradingShopRecordVO1 = tradingShopRecordVOList.get(0);
            if (tradingShopRecordVO1.getIngot() >= tradingShopRecordVO.getIngot()){
                tradingShopRouteUtil.sendTradingShopResponse(CommonTradingShop.ERROR,
                        "出价必须比当前出价最高者价格高！", userId);
                return;
            }
            //扣报价全额
            addAuctionTradingShopRecord(user, tradingShopVO, tradingShopRecordVO,
                    tradingShopRecordVO.getIngot());
        }else {
            TradingShopRecordVO tradingShopRecordVO2 = tradingShopRecordVOList.get(0);
            if (tradingShopRecordVO2.getIngot() >= tradingShopRecordVO.getIngot()){
                tradingShopRouteUtil.sendTradingShopResponse(CommonTradingShop.ERROR,
                        "出价必须比当前出价最高者价格高！", userId);
                return;
            }
            //扣除和之前报价的差价
            addAuctionTradingShopRecord(user, tradingShopVO, tradingShopRecordVO,
                    tradingShopRecordVO.getIngot() - tradingShopRecordVO1.getIngot());
        }
    }

    /**
     * 用户金币扣除和记录保存
     * @param user
     * @param tradingShopVO
     * @param tradingShopRecordVO
     * @param buyIngot 如果是自己第一次竞拍就是出价全额，如果不是第一次就是自己之前出价记录中最高的价格和当前出价的差值
     */
    public void addAuctionTradingShopRecord(UserServiceCache.User user, TradingShopVO tradingShopVO,
                                            TradingShopRecordVO tradingShopRecordVO, long buyIngot){
        //用户金币扣除
        user.getUserVO().setIngot(user.getUserVO().getIngot() - buyIngot);
        asynDBManager.distributeWork(user.getUserVO().getUserId(), () -> userService.update(new UserDO(user.getUserVO())));
        //添加拍卖记录
        tradingShopCache.getTradingShopInMap().get(tradingShopVO
                .getTradingShopId()).addTradingShopRecordVO(tradingShopRecordVO);
        asynDBManager.distributeWork(user.getUserVO().getUserId(), () -> tradingShopRecordService.save(tradingShopRecordVO));
        tradingShopManager.getAll(userId);
        tradingShopRouteUtil.sendTradingShopResponse(CommonTradingShop.BUY_AUCTION, "竞拍成功！", userId);
    }
}
